import math
import os
import uuid
from datetime import datetime
from pathlib import Path

import aiofiles
from fastapi import APIRouter, UploadFile, File, HTTPException
from fastapi.logger import logger

from ..config.db import SessionDep
from ..models.task import Task, TaskStatus, find_task_by_id, save_task
from ..schedule.task_schedule import task_schedule_handler

router = APIRouter()

# 文件暂存未知
UPLOAD_DIR = Path("workspace/uploads")
UPLOAD_DIR.mkdir(parents=True, exist_ok=True)


@router.post("")
async def create_task(
        session: SessionDep,
        file: UploadFile = File(...)
):
    """
    创建任务
    :param session:
    :param file: 任务文件
    :return:
    """
    save_path = await save_file(file)
    try:
        task = Task(
            input_path=str(save_path.resolve()),
            status=TaskStatus.PENDING,
        )

        task = await save_task(session, task)

        await task_schedule_handler.trigger_schedule()

        return {"id": task.id}
    except Exception as e:
        save_path.unlink()
        logger.error(f"创建任务失败: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/{task_id}")
async def task_details(
        session: SessionDep,
        task_id: int
):
    """
     获取任务结果
    :param session:
    :param task_id: 任务id
    :return:
    """

    task = await find_task_by_id(session, task_id)
    if not task:
        raise HTTPException(status_code=404, detail=f"任务不存在")

    now = datetime.now()
    start_time = task.start_execution_time or now
    end_time = task.end_execution_time or now

    return {
        "title": task.title or "",
        "content": task.content or "",
        "status": task.status,
        "error_msg": task.error_msg or "",
        "execution_time": math.floor((end_time - start_time).total_seconds()),
    }


async def save_file(file: UploadFile) -> Path:
    """
     保存文件到本地
    :param file: 上传的文件
    :return:
    """
    original_name = os.path.basename(file.filename)
    save_path = UPLOAD_DIR / f"{uuid.uuid4()}_{original_name}"
    async with aiofiles.open(save_path, "wb") as buffer:
        while content := await file.read(1024):
            await buffer.write(content)
    return save_path
